package com.cardone.common.util;

import java.lang.reflect.Type;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

/**
 * bean 工具
 *
 * @author yaohaitao
 *
 */
public class MapperUtils {
	private static Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();

	private static Type mapType = new TypeToken<Map<String, Object>>() {
		/**
		 *
		 */
		private static final long serialVersionUID = -9096570133906255553L;
	}.getType();

	/**
	 * 生成gson
	 *
	 * @param datePattern
	 *          日期结构
	 * @return
	 */
	private static Gson builderGson(final String datePattern) {
		final GsonBuilder gsonBuilder = new GsonBuilder();

		if (StringUtils.isNotBlank(datePattern)) {
			gsonBuilder.setDateFormat(datePattern);
		}

		final Gson gson = gsonBuilder.create();

		return gson;
	}

	/**
	 * 获取bean关于json
	 *
	 * @param mappedClass
	 *          映射类型
	 * @param jsonString
	 *
	 * @return bean @
	 */
	public static <T> T getBeanForJson(final Class<T> mappedClass, final String jsonString) {
		if (StringUtils.isBlank(jsonString)) {
			return null;
		}

		return MapperUtils.gson.fromJson(jsonString, TypeToken.of(mappedClass).getType());
	}

	/**
	 * 获取bean关于json
	 *
	 * @param mappedClass
	 *          映射类型
	 * @param paramName
	 *          参数名称
	 * @param map
	 * @return @
	 */
	public static <T> T getBeanForJson(final Class<T> mappedClass, final String paramName, final Map<String, Object> map) {
		final Object paramJsonObject = MapUtils.getObject(map, paramName);

		if (paramJsonObject == null) {
			return null;
		}

		return MapperUtils.toBean(mappedClass, paramJsonObject);
	}

	/**
	 * 获取bean关于json
	 *
	 * @param mappedClass
	 *          映射类型
	 * @param paramName
	 *          参数名称
	 * @param jsonString
	 *
	 * @return bean @
	 */
	public static <T> T getBeanForJson(final Class<T> mappedClass, final String paramName, final String jsonString) {
		final Object paramJsonObject = MapperUtils.getObjectForJson(paramName, jsonString);

		if (paramJsonObject == null) {
			return null;
		}

		return MapperUtils.toBean(mappedClass, paramJsonObject);
	}

	/**
	 * 获取bean关于json
	 *
	 * @param Type
	 *          映射类型
	 * @param paramName
	 *          参数名称
	 * @param map
	 * @return @
	 */
	public static <T> T getBeanForJson(final Type mappedType, final String paramName, final Map<String, Object> map) {
		final Object paramJsonObject = MapUtils.getObject(map, paramName);

		if (paramJsonObject == null) {
			return null;
		}

		return MapperUtils.toBean(mappedType, paramJsonObject);
	}

	/**
	 * 获取bean关于json
	 *
	 * @param Type
	 *          映射类型
	 * @param paramName
	 *          参数名称
	 * @param jsonString
	 *
	 * @return bean @
	 */
	public static <T> T getBeanForJson(final Type mappedType, final String paramName, final String jsonString) {
		final Object paramJsonObject = MapperUtils.getObjectForJson(paramName, jsonString);

		if (paramJsonObject == null) {
			return null;
		}

		return MapperUtils.toBean(mappedType, paramJsonObject);
	}

	/**
	 * @param mappedClass
	 * @param src
	 * @return
	 */
	public static <T> T getBeanForObject(final Class<T> mappedClass, final Object src) {
		if (src == null) {
			return null;
		}

		final String paramJsonString = MapperUtils.gson.toJson(src);

		return MapperUtils.gson.fromJson(paramJsonString, TypeToken.of(mappedClass).getType());
	}

	/**
	 * 获取键值对
	 *
	 * @param jsonString
	 * @return 键值对 @
	 */
	public static Map<String, Object> getMapForJson(final String jsonString) {
		if (StringUtils.isBlank(jsonString)) {
			return null;
		}

		return MapperUtils.gson.fromJson(jsonString, MapperUtils.mapType);
	}

	/**
	 * 获取对象
	 *
	 * @param paramName
	 *          参数名称
	 * @param jsonString
	 * @return 对象 @
	 */
	public static Object getObjectForJson(final String paramName, final String jsonString) {
		final Map<String, Object> model = MapperUtils.getMapForJson(jsonString);

		return MapUtils.getObject(model, paramName);
	}

	/**
	 * 获取bean关于json
	 *
	 * @param mappedClass
	 *          映射类型
	 * @param src
	 * @return @
	 */
	public static <T> T toBean(final Class<T> mappedClass, final Object src) {
		return toBean(mappedClass, src, null);
	}

	/**
	 * 获取bean关于json
	 *
	 * @param mappedClass
	 *          映射类型
	 * @param src
	 * @param datePattern
	 *          日期结构
	 * @return @
	 */
	public static <T> T toBean(final Class<T> mappedClass, final Object src, final String datePattern) {
		final Gson gson = MapperUtils.builderGson(datePattern);

		final String srcJsonString = gson.toJson(src);

		return gson.fromJson(srcJsonString, TypeToken.of(mappedClass).getType());
	}

	/**
	 * 获取bean关于json
	 *
	 * @param Type
	 *          映射类型
	 *
	 * @param src
	 *          参数名称
	 *
	 * @return @
	 */
	public static <T> T toBean(final Type mappedType, final Object src) {
		return toBean(mappedType, src, null);
	}

	/**
	 * 获取bean关于json
	 *
	 * @param Type
	 *          映射类型
	 *
	 * @param src
	 *          参数名称
	 * @param datePattern
	 *          日期结构
	 *
	 * @return
	 */
	public static <T> T toBean(final Type mappedType, final Object src, final String datePattern) {
		final Gson gson = MapperUtils.builderGson(datePattern);

		final String srcJsonString = gson.toJson(src);

		return gson.fromJson(srcJsonString, mappedType);
	}

	/**
	 * 转为json
	 *
	 * @param src
	 *          object
	 * @return string
	 */
	public static String toJson(final Object src) {
		return MapperUtils.gson.toJson(src);
	}
}
